{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Y2eqHW0TK87s"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/drive/1p7CfHfWGj61rBE8U_uih-IIW98kr3nuw?usp=sharing\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"></a>\n",
        "\n",
        "### Automatic Reasoning and Tool-Use (ART)\n",
        "\n",
        "ART is an advanced prompting method that combines reasoning with automated tool selection and use.\n",
        "\n",
        "### Key points:\n",
        "\n",
        "* **Core concept:** Enable language models to autonomously reason about problems and select/use appropriate tools.\n",
        "\n",
        "* **Components:**\n",
        "  * Reasoning module\n",
        "  * Tool selection mechanism\n",
        "  * Tool use interface\n",
        "\n",
        "* **Process:**\n",
        "  * Analyze the problem through reasoning\n",
        "  * Identify and select relevant tools\n",
        "  * Use tools to gather information or perform actions\n",
        "  * Integrate tool outputs into the reasoning process\n",
        "\n",
        "* **Advantages:**\n",
        "  * Enhances problem-solving capabilities\n",
        "  * Allows for more complex, multi-step tasks\n",
        "\n",
        "* **Applications:**\n",
        "  * Data analysis\n",
        "  * Web-based research\n",
        "  * Complex decision-making scenarios\n",
        "\n",
        "* **Implementation:**\n",
        "  * Define a set of available tools and their functions\n",
        "  * Design prompts that encourage tool consideration\n",
        "  * Implement feedback loops between reasoning and tool use\n",
        "\n",
        "* **Challenges:**\n",
        "  * Ensuring appropriate tool selection\n",
        "  * Managing context across multiple tool uses\n",
        "\n",
        "* **Example structure:**\n",
        "  * Thought: [Reasoning about the problem]\n",
        "  * Tool Selection: [Choose appropriate tool]\n",
        "  * Tool Use: [Apply selected tool]\n",
        "  * Integration: [Incorporate tool output into reasoning]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "XNrPX8MZJm9e",
        "outputId": "a79577d0-400c-4610-db77-5652b323ce1b"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\u001b[?25l   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/121.9 kB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m121.9/121.9 kB\u001b[0m \u001b[31m3.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25h"
          ]
        }
      ],
      "source": [
        "!pip install -q -U langchain-groq>=0.2.4"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "metadata": {
        "id": "gOLahJCEJv6_"
      },
      "outputs": [],
      "source": [
        "from langchain_groq import ChatGroq\n",
        "from langchain.prompts import ChatPromptTemplate\n",
        "from IPython.display import display, Markdown\n",
        "from datetime import datetime, date\n",
        "import json"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "id": "I6qvHWQsJxWq"
      },
      "outputs": [],
      "source": [
        "import os\n",
        "import getpass"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "GaoPiWagJyoV"
      },
      "source": [
        "### 🔑 Provide Groq API Key\n",
        "\n",
        "- [Groq API Key](https://console.groq.com/keys)\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "f-Ioab8HJ037",
        "outputId": "f6df82e9-e324-4df1-aca5-c79734793113"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "··········\n"
          ]
        }
      ],
      "source": [
        "os.environ[\"GROQ_API_KEY\"] = getpass.getpass()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "RzCcry2GJ2Z1"
      },
      "outputs": [],
      "source": [
        "llm = ChatGroq(\n",
        "    model=\"llama-3.1-8b-instant\",\n",
        "    temperature=0.5\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "metadata": {
        "id": "RCjbg-xkJ4cY"
      },
      "outputs": [],
      "source": [
        "# Define available tools\n",
        "def calculate_days(date_string):\n",
        "    target_date = datetime.strptime(date_string, \"%Y-%m-%d\").date()\n",
        "    current_date = date.today()\n",
        "    return (target_date - current_date).days\n",
        "\n",
        "tools = {\n",
        "    \"calculator\": lambda x: eval(x),\n",
        "    \"date\": lambda: date.today().strftime(\"%Y-%m-%d\"),\n",
        "    \"weather\": lambda city: f\"The weather in {city} is sunny with a high of 25°C.\",\n",
        "    \"days_between\": calculate_days\n",
        "}\n",
        "\n",
        "# ART Prompt\n",
        "art_prompt = ChatPromptTemplate.from_messages(\n",
        "    [\n",
        "        (\"system\", \"\"\"You are an AI assistant capable of breaking down complex tasks, identifying necessary tools, and applying them to solve problems. You have access to the following tools:\n",
        "          1. calculator: Performs mathematical calculations. Input should be a mathematical expression.\n",
        "          2. date: Returns the current date.\n",
        "          3. weather: Provides weather information for a given city.\n",
        "          4. days_between: Calculates the number of days between the current date and a given date (format: YYYY-MM-DD).\n",
        "          For each step in your reasoning, if a tool is needed, specify it in the following JSON format:\n",
        "          {{\"tool\": \"tool_name\", \"input\": \"tool_input\"}}\n",
        "          Your final answer should not be in JSON format.\"\"\"),\n",
        "        (\n",
        "            \"human\", \"\"\"Task: {task}\n",
        "              Break down this task and solve it step by step. For each step, explain your reasoning and use tools when necessary.\n",
        "              Your response:\"\"\"\n",
        "        ),\n",
        "    ]\n",
        ")\n",
        "\n",
        "def art_response(task):\n",
        "    chain = art_prompt | llm\n",
        "    raw_response = chain.invoke({\"task\": task}).content\n",
        "    # Process the response to use tools\n",
        "    lines = raw_response.split(\"\\n\")\n",
        "    processed_response = []\n",
        "\n",
        "    for line in lines:\n",
        "        if line.strip().startswith(\"{\") and line.strip().endswith(\"}\"):\n",
        "            try:\n",
        "                tool_call = json.loads(line.strip())\n",
        "                if \"tool\" in tool_call and \"input\" in tool_call:\n",
        "                    if tool_call[\"tool\"] in tools:\n",
        "                        # Handle different tools properly\n",
        "                        if tool_call[\"tool\"] == \"date\":\n",
        "                            tool_result = tools[tool_call[\"tool\"]]()\n",
        "                        else:\n",
        "                            tool_result = tools[tool_call[\"tool\"]](tool_call[\"input\"])\n",
        "\n",
        "                        processed_response.append(\n",
        "                            f\"Using {tool_call['tool']}: {tool_call['input']}\"\n",
        "                        )\n",
        "                        processed_response.append(f\"Result: {tool_result}\")\n",
        "                    else:\n",
        "                        processed_response.append(\n",
        "                            f\"Error: Tool '{tool_call['tool']}' not found.\"\n",
        "                        )\n",
        "                else:\n",
        "                    processed_response.append(line)\n",
        "            except json.JSONDecodeError:\n",
        "                processed_response.append(line)\n",
        "        else:\n",
        "            processed_response.append(line)\n",
        "\n",
        "    return \"\\n\".join(processed_response)\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 379
        },
        "id": "kY1AoektWzh_",
        "outputId": "bf33d070-2303-4a8c-e70e-856490180844"
      },
      "outputs": [
        {
          "data": {
            "text/markdown": [
              "**Automatic Reasoning and Tool-Use (ART) Response:**\n",
              "Task: Calculate the number of days between the current date and July 4, 2025. Then, provide the weather forecast for New York City.\n",
              "Let's break down the task into smaller steps and solve it step by step.\n",
              "\n",
              "Step 1: Calculate the number of days between the current date and July 4, 2025.\n",
              "\n",
              "To do this, we need to calculate the difference between the current date and July 4, 2025. We can use the \"date\" tool to get the current date, and then use the \"days_between\" tool to calculate the number of days between the current date and July 4, 2025.\n",
              "\n",
              "Using date: \n",
              "Result: 2025-02-25\n",
              "\n",
              "This will give us the current date. Let's assume the current date is 2023-09-01.\n",
              "\n",
              "Next, we can use the \"days_between\" tool to calculate the number of days between the current date (2023-09-01) and July 4, 2025.\n",
              "\n",
              "Using days_between: 2025-07-04\n",
              "Result: 129\n",
              "\n",
              "This will give us the number of days between the current date and July 4, 2025.\n",
              "\n",
              "Step 2: Provide the weather forecast for New York City.\n",
              "\n",
              "To do this, we can use the \"weather\" tool and input the city name as \"New York City\".\n",
              "\n",
              "Using weather: New York City\n",
              "Result: The weather in New York City is sunny with a high of 25°C.\n",
              "\n",
              "This will give us the current weather forecast for New York City.\n",
              "\n",
              "In conclusion, the number of days between the current date (2023-09-01) and July 4, 2025 is 1091 days. The current weather forecast for New York City is [insert weather forecast here]."
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# Example usage\n",
        "task = \"Calculate the number of days between the current date and July 4, 2025. Then, provide the weather forecast for New York City.\"\n",
        "response = art_response(task)\n",
        "display(\n",
        "    Markdown(\n",
        "        f\"\"\"**Automatic Reasoning and Tool-Use (ART) Response:**\n",
        "Task: {task}\n",
        "{response}\"\"\"\n",
        "    )\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "ofPh8APtYbCT"
      },
      "outputs": [],
      "source": []
    }
  ],
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
